// 原文：https://blog.csdn.net/wag2765/article/details/84794067
/************************************************************************/
/*测试std::mutex和std::atomic的性能对比  */
/************************************************************************/
// clang++ -o test_atom -std=c++14 -O1 -g ./test_atom.cpp

#include <time.h>  
#include <thread>
#include <list> 
#include <atomic>
#include <mutex>
#include <ctime>
#include <chrono>
 
#define LOOP_COUNT 12500000
#define THREAD_COUNT 8
 
std::atomic<unsigned int>* atomic_array;
 
std::mutex m;
unsigned int* int_array;
 
void atomic_fun()
{
	for (int i = 0; i < LOOP_COUNT; i++)
	{
		atomic_array[0]++;
		atomic_array[1]--;
	}
}
 
void mutex_fun()
{
	for (int i = 0; i < LOOP_COUNT; i++)
	{
		{
			std::unique_lock<std::mutex> lk(m);
			int_array[0]++;
		}
		{
			std::unique_lock<std::mutex> lk(m);
			int_array[1]--;
		}
	}
}
 
 
void test(void (*func)())
{
	atomic_array = new std::atomic<unsigned int>[2];
	atomic_array[0] = 0;
	atomic_array[1] = LOOP_COUNT * THREAD_COUNT;
 
	int_array = new unsigned int[2];
	int_array[0] = 0;
	int_array[1] = LOOP_COUNT * THREAD_COUNT;
 
	std::thread** tarray = new std::thread*[THREAD_COUNT];
 
	auto start = std::chrono::steady_clock::now();
 
	for (int i = 0; i < THREAD_COUNT; i++)
	{
		tarray[i] = new std::thread(func);
	}
 
	for (int i = 0; i < THREAD_COUNT; i++)
	{
		tarray[i]->join();
	}

	auto end = std::chrono::steady_clock::now();
	auto int_ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
	printf("cost:%lldms\n", int_ms.count());
 
 
	for (int i = 0; i < THREAD_COUNT; i++)
	{
		delete tarray[i];
	}
	delete[] tarray;
}
 
int main(int ,char* [])
{
	//为了排除测试程序的无关因素，测试时只开启一个：blocking或者nonblocking。
	test(&atomic_fun);
	// cost:2644ms
	//printf("[atomic]0:%d 1:%d\n", atomic_array[0], atomic_array[1]);
 
	//cost:9500ms
	//[mutex]0 : 100000000 1 : 0
	//test(&mutex_fun);
	//printf("[mutex]0:%d 1:%d\n", int_array[0], int_array[1]);
}
